﻿namespace DslEditorPowerToy.Controls.Languages.Designers
{
    using DslEditorPowerToy.Controls;
    using DslEditorPowerToy.Controls.Languages;
    using Microsoft.VisualStudio.Modeling.Shell;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;

    public abstract class EditorHostContainerBase : UserControl, IEditorHostContainer
    {
        private ModelingDocView _docView;
        private EditorHostControl _editorHostControl;
        private ComponentSelectionBroker _selectionBroker;

        [CLSCompliant(false)]
        public EditorHostContainerBase(ModelingDocView docView, Assembly editorDeclaringAssembly)
        {
            this._docView = docView;
            this._editorHostControl = new EditorHostControl(editorDeclaringAssembly, new Guid());
            this.InitialiseControls();
        }

        private void _selectionBroker_EnvironmentSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.OnEnvironmentSelectionChanged(e.SelectionProvider, e.Source);
        }

        public void ActivateEditor(Guid editorId)
        {
            this._editorHostControl.ActivateEditor(editorId);
        }

        protected override void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    if (this._editorHostControl != null)
                    {
                        this._editorHostControl.EditorChanged -= new EventHandler(this.editorHostControl_EditorChanged);
                        this._editorHostControl.Dispose();
                    }
                    if (this._selectionBroker != null)
                    {
                        this._selectionBroker.EnvironmentSelectionChanged -= new SelectionChangedEventHandler(this._selectionBroker_EnvironmentSelectionChanged);
                        this._selectionBroker.Dispose();
                    }
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }

        private void editorHostControl_EditorChanged(object sender, EventArgs e)
        {
            this.OnEditorChanged();
        }

        private void InitialiseControls()
        {
            base.SuspendLayout();
            this._editorHostControl.Location = new Point(0, 0);
            this._editorHostControl.Dock = DockStyle.Fill;
            this._editorHostControl.EditorChanged += new EventHandler(this.editorHostControl_EditorChanged);
            base.Controls.Add(this._editorHostControl);
            base.ResumeLayout(false);
            base.PerformLayout();
        }

        protected virtual void OnEditorChanged()
        {
        }

        protected virtual void OnEnvironmentSelectionChanged(ISelectionProvider selectionProvider, SelectionChangeSource source)
        {
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this._selectionBroker = new ComponentSelectionBroker(this._docView, this._editorHostControl);
            this._selectionBroker.RegisterDocView(this._docView);
            this._selectionBroker.EnvironmentSelectionChanged += new SelectionChangedEventHandler(this._selectionBroker_EnvironmentSelectionChanged);
        }

        public IHostedEditorDefinition CurrentEditor
        {
            get
            {
                return this._editorHostControl.CurrentEditor;
            }
        }

        public List<IHostedEditorDefinition> Editors
        {
            get
            {
                return this._editorHostControl.GetEditors();
            }
        }

        public NavigationOrientationStyle NavigationStyle
        {
            get
            {
                return this._editorHostControl.NavigationStyle;
            }
            set
            {
                this._editorHostControl.NavigationStyle = value;
            }
        }
    }
}

